home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Delphi Developer's Kit 1996
/
Delphi Developer's Kit 1996.iso
/
power
/
lexscan
/
strutils.pas
< prev
Wrap
Pascal/Delphi Source File
|
1995-12-22
|
12KB
|
474 lines
========
Newsgroups: comp.lang.pascal.delphi.components
Subject: Lexical Scanner [3/4]
From: jbui@scd.hp.com (Joseph Bui)
Date: 27 Jul 1995 16:59:40 GMT
{
************************ STRUTILS.PAS ***********************
}
{$define NO_EXCEPTIONS}
unit Strutils;
interface
uses
SysUtils, TypInfo;
const
Null = '';
type
TChars = set of char;
{basic string manipulation}
function before(const Search, Find: string): string;
function after(const Search, Find: string): string;
function squish(const Search: string): string;
function trim(const Search: string): string;
function reverse(const Search: string): string;
{library routine extensions}
function RPos(const Find, Search: string): byte;
function SetPos(const Search: string; {const Find: array of const}
const Find: TChars): byte;
function SetRPos(const Search: string; {const Find: array of const}
const Find: TChars): byte;
{complex string manipulation}
function inside(const Search, Front, Back: string): string;
function leftside(const Search, Front, Back: string): string;
function rightside(const Search, Front, Back: string): string;
{list manipulation}
function last(const Search: string): string;
function lrest(const Search: string): string;
function extract(const Search: string; const Start, Count: byte;
const Separator, QuoteChar: char): string;
function match(const Search, Find: string;
const Separator, QuoteChar: char): byte;
{numeric strings}
function IsAnInt(const Search: string): boolean;
function IsAFloat(const Search: string): boolean;
function IsANum(const Search: string): boolean;
function StrToNum(const Search: string): extended;
function StrType(const Search: string): TTypeKind;
implementation
const
{
The values of BlackSpaces and WhiteSpaces should be changed for
non-USA users.
}
BlackSpaces = [#33..#126];
WhiteSpaces = [#0..#32];
Digits = ['0'..'9'];
HexDigits = Digits + ['A'..'F', 'a'..'f'];
{**************** Basic String Manipulation *******************}
{
before() returns everything before the first occurance of
Find in Search. If Find does not occur in Search, Search is
returned.
}
function before(const Search, Find: string): string;
var
index: byte;
begin
index:=Pos(Find, Search);
if index = 0 then
Result:=Search
else
Result:=Copy(Search, 1, index - 1);
end;
{
after() returns everything after the first occurance of
Find in Search. If Find does not occur in Search, a null
string is returned.
}
function after(const Search, Find: string): string;
var
index: byte;
begin
index:=Pos(Find, Search);
if index = 0 then
Result:=Null
else
Result:=Copy(Search, index + Length(Find), 255);
end;
{
squish() returns a string with all WhiteSpaces compressed into
single #32's. Leading and trailing WhiteSpaces are removed.
}
function squish(const Search: string): string;
var
Index: byte;
AddSpace: boolean;
begin
AddSpace:=False;
Result:=Null;
for Index:=1 to Length(Search) do
if Search[Index] in BlackSpaces then
begin
AppendStr(Result, Search[Index]);
AddSpace:=True;
end
else
if AddSpace then
begin
AppendStr(Result, #32);
AddSpace:=False;
end;
if Result[Length(Result)] = #32 then
Result[0]:=Chr(Length(Result) - 1);
end;
{
trim() returns a string with all right and left WhiteSpaces removed.
}
function trim(const Search: string): string;
var
Index: byte;
begin
for Index:=1 to Length(Search) do
if Search[Index] in BlackSpaces then
Break;
Result:=Copy(Search, Index, 255);
for Index:=Length(Result) downto 1 do
if Search[Index] in BlackSpaces then
Break;
Result:=Copy(Result, 1, Index);
end;
{
reverse() returns Search reversed by character.
}
function reverse(const Search: string): string;
var
Index: byte;
begin
Result:=Null;
for Index:=Length(Search) downto 1 do
AppendStr(Result, Search[Index]);
end;
{*************** Library Routine Extensions *******************}
{
RPos() returns the index of the first character of the last
occurance of Find in Search. Returns 0 if Find does not occur
in Search. Like Pos() but searches in reverse.
}
function RPos(const Find, Search: string): byte;
begin
Result:=Pos(reverse(Find), reverse(Search));
if Result > 0 then
Result:=Length(Search) - Result + 1;
end;
{
SetPos() returns the index of the first occurance of an element
of Find in Search. If no elements of Find occur in Search then
0 is returned.
}
function SetPos(const Search: string; const Find: TChars): byte;
begin
for Result:=1 to Length(Search) do
if Search[Result] in Find then
Exit;
Result:=0;
end;
{
SetRPos() returns the index of the last occurance of an element
of Find in Search. If no elements of Find occur in Search then
0 is returned.
}
function SetRPos(const Search: string; const Find: TChars): byte;
begin
for Result:=Length(Search) downto 1 do
if Search[Result] in Find then
Exit;
Result:=0;
end;
{***************** Complex String Manipulation ****************}
{
inside() returns the string between the most inside nested
Front ... Back pair.
}
function inside(const Search, Front, Back: string): string;
var
Index, Len: byte;
begin
Len:=Pos(Back, Search);
Result:=Null;
if Len > 0 then
begin
Index:=RPos(Front, Copy(Search, 1, Len - 1));
if Index > 0 then
Result:=Copy(Search, Index + Length(Front), Len - Index - Length(Front));
end;
end;
{
leftside() returns what is to the left of inside() or Search.
}
function leftside(const Search, Front, Back: string): string;
var
Index, Len: byte;
begin
Result:=Search;
Len:=Pos(Back, Search);
if Len > 0 then
begin
Index:=RPos(Front, Copy(Search, 1, Len - 1));
if Index > 0 then
Result:=Copy(Search, 1, Index - 1);
end;
end;
{
rightside() returns what is to the right of inside() or Null.
}
function rightside(const Search, Front, Back: string): string;
var
Index, Len: byte;
begin
Result:=Null;
Len:=Pos(Back, Search);
if Len > 0 then
begin
Index:=RPos(Front, Copy(Search, 1, Len - 1));
if Index > 0 then
Result:=Copy(Search, Len + Length(Back), 255);
end;
end;
{********************** List Manipulation *********************}
{
last() returns the last continuous set of BlackSpaces in
Search. Note: Returns Null if the last characters of Search
are WhiteSpaces.
}
function last(const Search: string): string;
var
Index: byte;
begin
Result:=Null;
Index:=Length(Search);
while (Search[Index] in BlackSpaces) and (Index > 0) do
Dec(Index);
Result:=Copy(Search, Index + 1, 255);
end;
{
lrest() returns everything last() does not return.
}
function lrest(const Search: string): string;
var
Index: byte;
begin
Result:=Null;
Index:=Length(Search);
while (Search[Index] in BlackSpaces) and (Index > 0) do
Dec(Index);
Result:=Copy(Search, 1, Index);
end;
{
extract() returns a list of Count items starting with Start from
the Separator separated list Search. Extract ignores any separator
located between paired QuoteChar's.
}
function extract(const Search: string; const Start, Count: byte;
const Separator, QuoteChar: char): string;
var
Index, Item: byte;
InQuote: boolean;
begin
InQuote:=False;
Item:=1;
Result:=Null;
for Index:=1 to Length(Search) do
begin
InQuote:=(Search[Index] = QuoteChar) xor InQuote;
if Item in [Start..Start + Count - 1] then
AppendStr(Result, Search[Index]);
Item:=Item + Ord((Search[Index] = Separator) and not InQuote);
if Item = (Start + Count) then
Break;
end;
if Result[Length(Result)] = Separator then
Result[0]:=Chr(Length(Result) - 1);
end;
{
match() returns the item position of Find in Search. If Find does not
occur in Search than 0 is returned. Search is a list of Separator
separated items. The item position of the first element of the list is
1. Match ignores any separators located between paired QuoteChars.
}
function match(const Search, Find: string;
const Separator, QuoteChar: char): byte;
var
Index, Start: byte;
InQuote: boolean;
begin
InQuote:=False;
Result:=1;
Start:=1;
if Search = Find then
Exit;
for Index:=1 to Length(Search) do
begin
InQuote:=(Search[Index] = QuoteChar) xor InQuote;
if (Search[Index] = Separator) and not InQuote then
begin
if Find = Copy(Search, Start, Index - Start) then
Exit;
Inc(Result);
Start:=Index + 1;
end;
end;
Result:=0;
end;
{********************* Numeric Strings ************************}
{
IsAnInt() returns true if Search can be converted to an
integer. Uses exceptions unless NO_EXCEPTIONS is defined.
}
function IsAnInt(const Search: string): boolean;
var
Index: byte;
Started: boolean;
IsHex: boolean;
begin
{$ifdef NO_EXCEPTIONS}
Result:=True;
Started:=False;
IsHex:=False;
for Index:=1 to Length(Search) do
begin
if not Result then
Exit;
if Started then
Result:=(Search[Index] in Digits) or
(IsHex and (Search[Index] in HexDigits))
else
if (Search[Index] in BlackSpaces) then
begin
Started:=not (Search[Index] in ['+', '-']);
IsHex:=Search[Index] = '$';
Result:=(IsHex and (Index < Length(Search))) or (not Started) or (Search[Index] in Digits);
end;
end;
if not Started then Result:=False;
{$else}
try
StrToInt(Search);
Result:=True;
except
on EConvertError do
Result:=False;
end;
{$endif}
end;
{
IsAFloat() returns true if Search can be converted to a floating point.
Uses exceptions unless NO_EXCEPTIONS is defined.
}
function IsAFloat(const Search: string): boolean;
var
Index: byte;
Allowed: set of char;
Started: boolean;
begin
{$ifdef NO_EXCEPTIONS}
Result:=True;
Started:=False;
Allowed:=Digits + ['+', '-', '.'] + WhiteSpaces;
for Index:=1 to Length(Search) do
begin
Result:=(Search[Index] in Allowed);
if not Result then
Exit;
if (not Started) and (Search[Index] in BlackSpaces) then
begin
Started:=True;
Allowed:=Allowed + ['E', 'e'] - ['+', '-'];
if (Search[Index] in ['+', '-']) and
((Index = Length(Search)) or
(Search[Index + 1] in WhiteSpaces)) then
begin
Result:=False;
exit;
end;
end;
case (Search[Index]) of
#0..#33 : if Started then Allowed:=WhiteSpaces;
'+', '-' : Allowed:=Allowed - ['+', '-'];
'.' : Allowed:=Allowed - ['.'];
'0'..'9' : Allowed:=Allowed - ['+', '-'];
'E', 'e' : Allowed:=Allowed + ['+', '-'] - ['E', 'e', '.'];
end;
end;
if not Started then Result:=False;
{$else}
try
StrToFloat(Search);
Result:=True;
except
on EConvertError do
Result:=False;
end;
{$endif}
end;
{
IsANum() returns true if Search can be converted to either
a floating point or an integer. Uses exceptions unless
NO_EXCEPTIONS is defined.
}
function IsANum(const Search: string): boolean;
begin
Result:=IsAnInt(Search) or IsAFloat(Search);
end;
{
StrToNum() returns Search as a floating point value. StrToNum
works on numbers in pascal hex notation. StrToNum will raise
an exception if Search can not be converted.
}
function StrToNum(const Search: string): extended;
begin
try
Result:=StrToFloat(Search);
except
Result:=StrToInt(Search);
end;
end;
{
StrType() returns tkInteger if Search can be converted to an
integer, tkFloat if Search can be converted to a floating
point and tkString otherwise.
}
function StrType(const Search: string): TTypeKind;
begin
if IsAnInt(Search) then
Result:=tkInteger
else
if IsAFloat(Search) then
Result:=tkFloat
else
Result:=tkString;
end;
end.